<?php

namespace App\Service;

use App\Models\Base\Order;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

/**
 * 订单逻辑.
 */
class OrderService
{
    /**
     * [getTodayOrder 获取当日订单列表].
     *
     * @Author   王文凡
     * @DateTime 2018-04-21
     *
     * @version  1.0
     *
     * @param string $top_num [description]
     *
     * @return array
     */
    public static function getTodayOrder($top_num = '')
    {
        $today = Carbon::today()->getTimestamp();
        $tomorrow = Carbon::tomorrow()->getTimestamp();
        $data = Order::where('status', 1)
            ->whereBetween('order_time', [$today, $tomorrow])
            ->select(DB::raw('id,player_id,player_name,sum(amount) as total_price,server_id'))
            ->groupBy('player_id')
            ->orderBy('total_price', 'desc')
            ->limit($top_num)
            ->get();
        if ($data->count()) {
            foreach ($data as $key => $val) {
                if ($val->server) {
                    $server_name = $val->server->name ?? '无';
                } else {
                    $server_name = '无';
                }
                $order_data = [$key, $val->player_id, $val->player_name, $val->total_price, $server_name];
                $orders[] = $order_data;
            }

            return $orders;
        } else {
            return [];
        }
    }

    /**
     * [getTodayOrderNum 获取当日订单数量].
     *
     * @Author   王文凡
     * @DateTime 2018-04-21
     *
     * @version  1.0
     *
     * @param string $start_time
     * @param string $end_time
     * @param int    $server_id
     *
     * @return int
     */
    public static function getTodayOrderNum($start_time = '', $end_time = '', $server_id = 0)
    {
        $today = $start_time ?: Carbon::today()->getTimestamp();
        $tomorrow = $end_time ?: Carbon::tomorrow()->getTimestamp();
        $order = Order::where('status', 1)
            ->whereBetween('order_time', [$today, $tomorrow]);
        if ($server_id) {
            $order->where('server_id', $server_id);
        }
        $order->get();

        return $order->count();
    }

    /**
     * [getDayOrderAmount 获取区间的订单金额].
     *
     * @Author   王文凡
     * @DateTime 2018-04-26
     *
     * @version  1.0
     *
     * @param string $start_time [description]
     * @param string $end_time   [description]
     *
     * @return int
     */
    public static function getDayOrderAmount($start_time, $end_time, $server_id = null, $channel_id = null)
    {
        $order = Order::where('status', 1)
            ->whereBetween('order_time', [$start_time, $end_time]);
        if ($server_id) {
            $order->where('server_id', $server_id);
        }
        if (null !== $channel_id) {
            $order->where('channel_id', $channel_id);
        }
        $price = $order->pluck('amount');

        return $price->sum();
    }

    /**
     * [payPlayerNum 付费人数].
     *
     * @Author   王文凡
     * @DateTime 2018-05-08
     *
     * @version  1.0
     *
     * @param string $start_time
     * @param string $end_time
     * @param int    $server_id
     * @param int    $channel_id
     *
     * @return int
     */
    public static function payPlayerNum($start_time, $end_time, $server_id = null, $channel_id = null)
    {
        $order = Order::whereBetween('order_time', [$start_time, $end_time])->Paid();
        if ($server_id) {
            $order->where('server_id', $server_id);
        }
        if (null !== $channel_id) {
            $order->where('channel_id', $channel_id);
        }
        $data = $order->groupBy('userid')->get();

        return $data->count();
    }

    /**
     * 通过用户ID集合查询订单.
     *
     * @param array  $userids
     * @param string $start_time
     * @param string $end_time
     * @param int    $channel_id
     *
     * @return Collection|null
     */
    public static function getUserOrders(array $userids, $start_time = null, $end_time = null, $channel_id = null)
    {
        $db = Order::whereIn('userid', arrayNumericString($userids));
        if ($start_time && $end_time) {
            $db = $db->whereBetween('order_time', [$start_time, $end_time]);
        } elseif ($end_time) {
            $db = $db->where('order_time', '<=', $end_time);
        }

        if (null !== $channel_id) {
            $db = $db->where('channel_id', $channel_id);
        }

        return  $db->Paid()->get();
    }

    /**
     * 获取不包含集合里的用户id的订单.
     *
     * @param array  $userids
     * @param string $start_time
     * @param string $end_time
     * @param int    $channel_id
     *
     * @return Collection|null
     */
    public static function getNotUserOrders(array $userids, $start_time = null, $end_time = null, $channel_id = null, $server_id)
    {
        $db = Order::whereNotIn('userid', $userids);
        if ($start_time && $end_time) {
            $db = $db->whereBetween('order_time', [$start_time, $end_time]);
        }
        if (null !== $channel_id) {
            $db = $db->where('channel_id', $channel_id);
        }
        if ($server_id) {
            $db = $db->where('server_id', $server_id);
        }

        return $db->Paid()->get();
    }

    /**
     * 通过角色ID集合查询订单.
     *
     * @param array  $roleIds
     * @param string $start_time
     * @param string $end_time
     *
     * @return Collection|null
     */
    public static function getRoleOrders(array $roleIds, $start_time = null, $end_time = null)
    {
        $db = Order::whereIn('player_id', $roleIds);
        if ($start_time && $end_time) {
            $db = $db->whereBetween('order_time', [$start_time, $end_time]);
        }

        return $db->Paid()->get();
    }

    /**
     * 通过角色id查询付费角色.
     *
     * @param array $role_ids
     *
     * @return mixed
     */
    public static function getUserByRoleId(array $role_ids)
    {
        return Order::whereIn('player_id', $role_ids)->Paid()->groupBy('player_id')->get();
    }

    /**
     * 获取不包含集合里的角色id的订单.
     *
     * @param array  $roleIds
     * @param string $start_time
     * @param string $end_time
     *
     * @return Collection|null
     */
    public static function getNotRoleOrders(array $roleIds, $start_time, $end_time)
    {
        return Order::whereNotIn('player_id', $roleIds)
            ->whereBetween('order_time', [$start_time, $end_time])
            ->Paid()->get();
    }

    /**
     * 分组查询用户充值金额.
     */
    public static function getUserOrderAmount()
    {
        return Order::selectRaw('userid,player_id,palyer_name,server_id,sum(amount)')->Paid()->groupBy('player_id')->get();
    }

    /**
     * 分组查询付费用户.
     *
     * @param array $userids
     * @param null  $start_time
     * @param null  $end_time
     * @param null  $channel_id
     *
     * @return Collection|null
     */
    public static function payUsers(array $userids, $start_time = null, $end_time = null, $channel_id = null)
    {
        $db = Order::whereIn('userid', arrayNumericString($userids));
        if ($start_time && $end_time) {
            $db = $db->whereBetween('order_time', [$start_time, $end_time]);
        }
        if (null !== $channel_id) {
            $db = $db->where('channel_id', $channel_id);
        }

        return  $db->Paid()->groupBy('userid')->get();
    }

    /**
     * 获取某一天充值档位数量.
     *
     * @param string $date_time
     * @param int    $server_id
     *
     * @return null|Collection
     */
    public static function getSomeDayPayLevelNumber($date_time = '', $server_id = null)
    {
        $subQuery = DB::table('orders')
            ->selectRaw("FROM_UNIXTIME(order_time, '%Y-%m-%d') AS date_time,charge_level,amount")
            ->where('status', 1);
        if ($server_id) {
            $subQuery = $subQuery->where('server_id', $server_id);
        }
        $result = DB::table(DB::raw("({$subQuery->toSql()}) as a"))
            ->mergeBindings($subQuery)
            ->select(DB::raw('a.charge_level,a.amount,count(a.charge_level) AS number'))
            ->where('date_time', $date_time)
            ->groupBy('charge_level')
            ->get();

        return $result;
    }

    /**
     * 截止到某一天的订单金额.
     *
     * @param $date_time
     * @param null $server_id
     * @param null $channel_id
     *
     * @return int
     */
    public static function somedayAgoOrderAmount($date_time, $server_id = null, $channel_id = null)
    {
        $db = Order::where('order_time', '<=', $date_time)->where('status', 1);
        if ($server_id) {
            $db = $db->where('server_id', $server_id);
        }
        if (null !== $channel_id) {
            $db = $db->where('channel_id', $channel_id);
        }

        return $db->get()->sum('amount');
    }
}
